home *** CD-ROM | disk | FTP | other *** search
/ The Best of Down Under Games / The Best of Down Under Games.iso / 3dfx Screen Savers / Power Render / SRC.ZIP / WINUTIL.C < prev   
C/C++ Source or Header  |  1997-07-10  |  15KB  |  704 lines

  1. #include <stdlib.h>
  2. #include <stdarg.h>
  3. #include <stdio.h>
  4. #include <assert.h>
  5.  
  6. #if defined(MSGLIDE) || defined (WTGLIDE)
  7. #include <glide.h>
  8. #endif
  9.  
  10. #include <dinput.h>
  11.  
  12. #define WIN32_LEAN_AND_MEAN
  13. #include <windows.h>
  14. #include <windowsx.h>
  15. #include "winutil.h"
  16.  
  17.  
  18. #define TITLE "Egerter Software 3Dfx ScreenSaver"
  19.  
  20. /* Forward declarations */
  21. HWND hWndMain;
  22. HINSTANCE  hInstance;    /* My instance handle */
  23.  
  24. char ** commandLineToArgv(LPSTR lpCmdLine, int *pArgc);
  25. void PRGUI_InitPath (char *startpath);
  26.  
  27. /* The following variables are used to simulate the input routines
  28.    from WGT 5.1 */
  29. char kbdon[256];
  30. static int keyhead = 0;
  31. static int keytail = 0;
  32. static int keyqueue[256] = {0};
  33.  
  34. PR_MouseCallback_data mouse;
  35. int PR_mx0, PR_my0, PR_mx1, PR_my1;
  36.  
  37.  
  38. /* Direct Input */
  39. #define WM_SYNCACQUIRE      (WM_USER + 0)
  40. LPDIRECTINPUT          g_pdi = NULL;
  41. LPDIRECTINPUTDEVICE    g_pMouse;
  42. LPDIRECTINPUTDEVICE    g_pKeyboard;
  43. HANDLE                 g_hevtMouse;
  44. int                    PR_AppActive;
  45. int                    fKeybdAcquired;
  46.  
  47.  
  48.  
  49. int minit (void)
  50. {
  51. HRESULT  err;
  52. GUID        guid = GUID_SysMouse;
  53.  
  54.  
  55.   if (g_pdi == NULL)
  56.   {
  57.    err = DirectInputCreate(hInstance, DIRECTINPUT_VERSION, &g_pdi, NULL);
  58.    if(FAILED(err))
  59.    {
  60.       MessageBox(NULL, "Unable to Create DirectInput Object",
  61.                  TITLE, MB_OK);
  62.       return FALSE;
  63.    }
  64.   }
  65.  
  66.  
  67.   /* Obtain an interface to the system mouse device. */
  68.   err = g_pdi->lpVtbl->CreateDevice(g_pdi, &guid, &g_pMouse, NULL);
  69.  
  70.   if (FAILED(err)) 
  71.     {
  72.      MessageBox(NULL, "Unable to Create DirectInput Mouse Device",
  73.                 TITLE, MB_OK);
  74.      return FALSE;
  75.     }
  76.  
  77.   /* Set the data format to "mouse format". */
  78.   err = g_pMouse->lpVtbl->SetDataFormat(g_pMouse, &c_dfDIMouse);
  79.  
  80.   if (FAILED(err)) 
  81.     {
  82.      MessageBox(NULL, "Unable to Set Mouse Format",
  83.                 TITLE, MB_OK);
  84.          return FALSE;
  85.     }
  86.  
  87.  
  88.   /* Set the cooperativity level. */
  89.   err = g_pMouse->lpVtbl->SetCooperativeLevel(g_pMouse, hWndMain,
  90.               DISCL_EXCLUSIVE | DISCL_FOREGROUND);
  91.  
  92.   if (FAILED(err)) 
  93.     {
  94.      MessageBox(NULL, "Unable to Set Cooperative Level",
  95.                 TITLE, MB_OK);
  96.      return FALSE;
  97.     }
  98.  
  99.   PR_mx0 = 0;
  100.   PR_my0 = 0;
  101.   PR_mx1 = 639;
  102.   PR_my1 = 479;
  103.   mouse.mx = 320;
  104.   mouse.my = 240;
  105.   mouse.but = 0;
  106.   return TRUE;
  107. }
  108.  
  109.  
  110.  
  111.  
  112. void mdeinit (void)
  113. {
  114.   if (g_pdi)      g_pdi   ->lpVtbl->Release(g_pdi), g_pdi    = NULL;
  115.   if (g_pMouse)   g_pMouse->lpVtbl->Release(g_pMouse), g_pMouse = NULL;
  116. }
  117.  
  118.  
  119. void msetbounds (int x0, int y0, int x1, int y1)
  120. {
  121.   PR_mx0 = x0;
  122.   PR_my0 = y0;
  123.   PR_mx1 = x1;
  124.   PR_my1 = y1;
  125. }
  126.  
  127.  
  128. void msetxy (int x0, int y0)
  129. {
  130.   mouse.mx = x0;
  131.   mouse.my = y0;
  132. }
  133.  
  134.  
  135. void noclick (void)
  136. {
  137.   while (mouse.but)
  138.     UpdateMessages ();
  139. }
  140.  
  141.  
  142. void PR_ReadMouse (void)
  143. {
  144. DIMOUSESTATE diMouseState;
  145.  
  146.   if (PR_AppActive)
  147.     {
  148.      if (g_pMouse->lpVtbl->GetDeviceState(g_pMouse,
  149.                         sizeof(diMouseState), &diMouseState) == DI_OK) 
  150.        {
  151.         mouse.mx += (int)diMouseState.lX;
  152.         mouse.my += (int)diMouseState.lY;
  153.         mouse.but = (diMouseState.rgbButtons[0]>0) + 
  154.                    ((diMouseState.rgbButtons[1]>0)<<1) +
  155.                    ((diMouseState.rgbButtons[2]>0)<<2);
  156.        }
  157.     }
  158.  
  159.   /* Clip the cursor to our client area */
  160.   if (mouse.mx < PR_mx0)
  161.       mouse.mx = PR_mx0;
  162.   if (mouse.mx > PR_mx1) 
  163.       mouse.mx = PR_mx1;
  164.  
  165.   if (mouse.my < PR_my0)
  166.       mouse.my = PR_my0;
  167.   if (mouse.my > PR_my1) 
  168.       mouse.my = PR_my1;
  169. }
  170.  
  171.  
  172. void PR_MouseSyncAcquire (HWND hwnd)
  173. {
  174.     if (PR_AppActive) {
  175.         if (g_pMouse) 
  176.                         g_pMouse->lpVtbl->Acquire(g_pMouse);
  177.     } else {
  178.         if (g_pMouse) 
  179.                         g_pMouse->lpVtbl->Unacquire(g_pMouse);
  180.     }
  181. //    InvalidateCursorRect(hwnd);
  182. }
  183.  
  184.  
  185.  
  186. int installkbd (void)
  187. {
  188. GUID     guid = GUID_SysKeyboard;
  189. HRESULT  err;
  190.  
  191.  
  192.   if (g_pdi == NULL)
  193.   {
  194.    err = DirectInputCreate(hInstance, DIRECTINPUT_VERSION, &g_pdi, NULL);
  195.    if(FAILED(err))
  196.    {
  197.       MessageBox(NULL, "Unable to Create DirectInput Object",
  198.                  TITLE, MB_OK);
  199.       return FALSE;
  200.    }
  201.   }
  202.  
  203.  
  204.   /* Obtain an interface to the system mouse device. */
  205.   err = g_pdi->lpVtbl->CreateDevice(g_pdi, &guid, &g_pKeyboard, NULL);
  206.   if (FAILED(err)) 
  207.     {
  208.      MessageBox(NULL, "Unable to Create DirectInput Keyboard Device",
  209.                 TITLE, MB_OK);
  210.      return FALSE;
  211.     }
  212.  
  213.   /* Set the data format to "mouse format". */
  214.   err = g_pKeyboard->lpVtbl->SetDataFormat(g_pKeyboard, &c_dfDIKeyboard);
  215.  
  216.   if (FAILED(err)) 
  217.     {
  218.      MessageBox(NULL, "Unable to Set Keyboard Format",
  219.                 TITLE, MB_OK);
  220.          return FALSE;
  221.     }
  222.  
  223.  
  224.   /* Set the cooperativity level. */
  225.   err = g_pKeyboard->lpVtbl->SetCooperativeLevel(g_pKeyboard, hWndMain,
  226.               DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
  227.  
  228.   if (FAILED(err)) 
  229.     {
  230.      MessageBox(NULL, "Unable to Set Keyboard Cooperative Level",
  231.                 TITLE, MB_OK);
  232.      return FALSE;
  233.     }
  234.  
  235.  
  236.     // try to acquire the keyboard
  237.    err = g_pKeyboard->lpVtbl->Acquire(g_pKeyboard);
  238.    if(SUCCEEDED(err))
  239.    {
  240.       // keyboard was acquired
  241.       fKeybdAcquired = TRUE;
  242.     }
  243.    else
  244.    {
  245.       // keyboard was NOT acquired
  246.       fKeybdAcquired = FALSE;
  247.    }
  248.  
  249.     // if we get here, all objects were created successfully
  250.     return TRUE;    
  251. }
  252.  
  253.  
  254.  
  255.  
  256. /*
  257. *
  258. * DI_ReadKeys
  259. *
  260. * Use DirectInput to read game-play keys
  261. *
  262. */
  263. void PR_ReadKeyboard(void)
  264. {
  265. HRESULT hRes;
  266.  
  267.   if (g_pKeyboard == NULL)
  268.     return;
  269.  
  270.    hRes = g_pKeyboard->lpVtbl->GetDeviceState(g_pKeyboard, sizeof(kbdon), kbdon);
  271.    if(hRes != DI_OK)
  272.     {
  273.       if(hRes == DIERR_INPUTLOST)
  274.       {
  275.          // we lost control of the keyboard, reacquire
  276.          fKeybdAcquired = FALSE;
  277.          if(SUCCEEDED(g_pKeyboard->lpVtbl->Acquire(g_pKeyboard)))
  278.          {
  279.             fKeybdAcquired = TRUE;
  280.          }
  281.       }
  282.  
  283.       // failed to read the keyboard, just return
  284.         return;
  285.     }
  286. }
  287.  
  288. void uninstallkbd (void)
  289. {
  290.   if(fKeybdAcquired)
  291.   {
  292.    g_pKeyboard->lpVtbl->Unacquire(g_pKeyboard);
  293.    fKeybdAcquired = FALSE;
  294.   }
  295.  
  296.   if(g_pKeyboard != NULL)
  297.     g_pKeyboard->lpVtbl->Release(g_pKeyboard);
  298.   g_pKeyboard = NULL;
  299. }
  300.  
  301.  
  302. BOOL PR_KeyboardSyncAcquire (void)
  303. {
  304.     // try to acquire the keyboard
  305.         if(g_pKeyboard != NULL)
  306.         {
  307.                 g_pKeyboard->lpVtbl->Acquire(g_pKeyboard);
  308.          }
  309.         else
  310.         {
  311.                 // keyboard device has not been created.
  312.                 fKeybdAcquired = FALSE;
  313.                 return FALSE;
  314.         }
  315.  
  316.         // if we get here, we are acquired again
  317.         fKeybdAcquired = TRUE;
  318.         return TRUE;
  319. }
  320.  
  321.  
  322.  
  323.  
  324. long FAR PASCAL MainWndproc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
  325. {
  326.     PAINTSTRUCT ps;
  327.     HDC         hdc;
  328.         LRESULT         lRc;
  329.  
  330.     switch( message )
  331.     {
  332.     case WM_SETCURSOR:
  333.          SetCursor(NULL);
  334.          return 0;
  335.          break;
  336.  
  337.     case WM_KEYDOWN:
  338.  
  339.                  if(!fKeybdAcquired)
  340.                    {
  341.             keyqueue[keyhead++] = wParam & 0xFF; 
  342.             keyhead &= 255;
  343.             return 0;
  344.                }
  345.         break;
  346.  
  347.     case WM_KEYUP:
  348.          return 0;
  349.          break;
  350.  
  351.         
  352.     case WM_ACTIVATE:
  353.         {
  354.          WORD fActive = LOWORD(wParam);
  355.          BOOL fMinimized = (BOOL) HIWORD(wParam);
  356.  
  357.          if ( ( fActive == WA_INACTIVE ) || fMinimized ) 
  358.              {
  359.               #if defined(MSGLIDE) || defined(WTGLIDE)
  360.               grSstControl (GR_CONTROL_DEACTIVATE);
  361.                           PR_AppActive = FALSE;
  362.                           PR_MouseSyncAcquire (hWnd);
  363.               #endif
  364.              } 
  365.          else 
  366.              {
  367.               #if defined(MSGLIDE) || defined(WTGLIDE)
  368.               grSstControl (GR_CONTROL_ACTIVATE);
  369.                           PR_AppActive = TRUE;
  370.               #endif
  371.  
  372.               PR_MouseSyncAcquire(hWnd);
  373.               PR_KeyboardSyncAcquire();
  374.               SetForegroundWindow (hWnd);
  375.              }
  376.        }
  377.        break;
  378.  
  379.  
  380.  
  381.     case WM_ENTERMENULOOP:
  382.     case WM_ENTERSIZEMOVE:
  383.          PR_AppActive = FALSE;
  384.          PR_MouseSyncAcquire(hWnd);
  385.          PR_KeyboardSyncAcquire();
  386.          break;
  387.  
  388.     case WM_EXITMENULOOP:
  389.     case WM_EXITSIZEMOVE:
  390.          PR_AppActive = GetActiveWindow() == hWnd;
  391.          PostMessage(hWnd, WM_SYNCACQUIRE, 0, 0L);
  392.          break;
  393.  
  394.     case WM_SYNCACQUIRE:
  395.          PR_MouseSyncAcquire (hWnd);
  396.          PR_KeyboardSyncAcquire();
  397.          break;
  398.                  
  399.     case WM_CREATE:
  400.         break;
  401.  
  402.     case WM_PAINT:
  403.         hdc = BeginPaint( hWnd, &ps );
  404.         EndPaint( hWnd, &ps );
  405.         return 1;
  406.  
  407.     case WM_CLOSE:
  408.         keyqueue[keyhead++] = 'q'; keyhead &= 255;
  409.         break;
  410.  
  411.     case WM_DESTROY:
  412.         PostQuitMessage (0);
  413.         break;
  414.  
  415.     case WM_MOVE:
  416.         #if defined(MSGLIDE) || defined(WTGLIDE)        
  417.         if (!grSstControl(GR_CONTROL_MOVE)) {
  418.             PostMessage( hWnd, WM_CLOSE, 0, 0 );
  419.             return 0;
  420.         }
  421.         #endif        
  422.         break;
  423.  
  424.         case WM_SYSCOMMAND:
  425.           switch (GET_WM_COMMAND_ID(wParam, lParam)) {
  426.         
  427.           case SC_SCREENSAVE:
  428.           break;
  429.         
  430.           default:
  431.           lRc = DefWindowProc(hWnd, message, wParam, lParam);
  432.           break;
  433.           }
  434.         
  435.         if (IsWindow(hWnd)) {
  436.          PR_MouseSyncAcquire (hWnd);
  437.          PR_KeyboardSyncAcquire();
  438.         }
  439.     return lRc;
  440.  
  441.     case WM_DISPLAYCHANGE:
  442.     case WM_SIZE:
  443.         {
  444.             extern void getWindowSize(float *width, float *height);
  445.             float  width, height;
  446.  
  447.             getWindowSize(&width, &height);
  448.             
  449.         }
  450.         
  451.         #if defined(MSGLIDE) || defined(WTGLIDE)
  452.         if (!grSstControl(GR_CONTROL_RESIZE)) {
  453.             PostMessage(hWnd, WM_CLOSE, 0, 0 );
  454.             return 0;
  455.         }
  456.         #endif
  457.         break;
  458.  
  459.  
  460.     default:
  461.         break;
  462.     }
  463.     return DefWindowProc(hWnd, message, wParam, lParam);
  464.  
  465. } /* MainWndproc */
  466.  
  467. /*
  468.  * initApplication
  469.  *
  470.  * Do that Windows initialization stuff...
  471.  */
  472. void PRGUI_LoadCursor3Dx (void);
  473.  
  474.   static BOOL initApplication( HANDLE hInstance, int nCmdShow )
  475. {
  476.     WNDCLASS    wc;
  477.     BOOL        rc;
  478.  
  479.  
  480. wc.style = CS_HREDRAW | CS_VREDRAW;
  481.     wc.lpfnWndProc = MainWndproc;
  482.     wc.cbClsExtra = 0;
  483.     wc.cbWndExtra = 0;
  484.     wc.hInstance = hInstance;
  485.     wc.hIcon = LoadIcon( NULL, IDI_APPLICATION);    /* generic icon */
  486.     wc.hCursor = NULL; //LoadCursor( NULL, IDC_ARROW );
  487.     wc.hbrBackground = GetStockObject( BLACK_BRUSH );
  488.     wc.lpszMenuName =  NULL;
  489.     wc.lpszClassName = "WinGlideClass";
  490.     rc = RegisterClass( &wc );
  491.     if( !rc )
  492.     {
  493.         return FALSE;
  494.     }
  495.  
  496.     hWndMain = CreateWindowEx(
  497.         WS_EX_TOPMOST,
  498.         "WinGlideClass",
  499.         TITLE,
  500.         WS_OVERLAPPED |     
  501.             WS_CAPTION  |     
  502.             WS_SYSMENU |     /* so we get an icon in the tray */
  503.             WS_THICKFRAME | 
  504.             WS_MAXIMIZEBOX | 
  505.             WS_MINIMIZEBOX | 
  506.             WS_VISIBLE,    /* so we don't have to call ShowWindow */
  507.             //WS_POPUP |      /* non-app window */
  508.  
  509.         CW_USEDEFAULT, 
  510.         CW_USEDEFAULT,
  511.         600,                /* GetSystemMetrics(SM_CXSCREEN), */
  512.         40,                /* GetSystemMetrics(SM_CYSCREEN), */
  513.         NULL,
  514.         NULL,
  515.         hInstance,
  516.         NULL );
  517.  
  518.     if (!hWndMain)
  519.       return FALSE;
  520.  
  521.   
  522.     if (!minit ()) 
  523.           {
  524.        DestroyWindow(hWndMain);
  525.        return 0;
  526.           }
  527.  
  528.  
  529.     ShowWindow (hWndMain, SW_NORMAL);
  530.     UpdateWindow (hWndMain);
  531.     
  532.         BringWindowToTop (hWndMain);
  533.         SetFocus (hWndMain);
  534.         
  535.         PR_AppActive = TRUE;
  536.     PR_MouseSyncAcquire (hWndMain);
  537.     return TRUE;
  538. } /* initApplication */
  539.  
  540. /*
  541.  * WinMain
  542.  */
  543. int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, 
  544.     LPSTR lpCmdLine, int nCmdShow )
  545. {
  546. LPSTR realcommand;
  547.     
  548.         if( !initApplication(hInstance, nCmdShow) )
  549.         return FALSE;
  550.  
  551.     {
  552.         int     argc;
  553.         char    **argv;
  554.  
  555. #ifdef __WATCOMC__
  556.         extern int WatMain(int argc, char **argv);
  557. #else
  558.         extern int main(int argc, char **argv);
  559. #endif
  560.                 realcommand = GetCommandLine ();
  561.         argv = commandLineToArgv(realcommand, &argc);
  562. //                PRGUI_InitPath (argv[0]);
  563.  
  564. #ifdef __WATCOMC__
  565.         WatMain (argc, argv);
  566. #else
  567.         main (argc, argv);
  568. #endif
  569.     }
  570.  
  571.     mdeinit ();
  572.     DestroyWindow(hWndMain);
  573.     return 0;
  574.  
  575. } /* WinMain */
  576.  
  577.  
  578.  
  579. /*
  580.  * Converts lpCmdLine to WinMain into argc, argv
  581.  */
  582. static char    *argvbuf[32];
  583. static char    cmdLineBuffer[1024];
  584. char **
  585. commandLineToArgv(LPSTR lpCmdLine, int *pArgc)
  586. {
  587.     char    *p, *pEnd;
  588.     int     argc = 0;
  589.  
  590.     if (lpCmdLine == NULL) {
  591.         *pArgc = argc;
  592.          return argvbuf;
  593.     }
  594.  
  595.     strcpy(cmdLineBuffer, lpCmdLine);
  596.     p = cmdLineBuffer;
  597.     pEnd = p + strlen(cmdLineBuffer);
  598.     if (pEnd >= &cmdLineBuffer[1022]) pEnd = &cmdLineBuffer[1022];
  599.  
  600.     fflush (stdout);
  601.  
  602.     while (1) {
  603.         /* skip over white space */
  604.         fflush(stdout);
  605.  
  606.         while (*p == ' ') p++;
  607.         if (p >= pEnd) break;
  608.  
  609.         while (*p == '\"') p++;
  610.         if (p >= pEnd) break;
  611.  
  612.         argvbuf[argc++] = p;
  613.         if (argc >= 32) break;
  614.  
  615.         /* skip till there's a 0 or a white space */
  616.         while (*p && (*p != ' ')) p++;
  617.                 
  618.  
  619.         if (*p == ' ') *p++ = 0;
  620.                 if (*p == '\"') *p++ = 0;
  621.     }
  622.  
  623.     *pArgc = argc;
  624.     return argvbuf;
  625. }
  626.  
  627.  
  628.  
  629. void getWindowSize(float *width, float *height)
  630. {
  631. RECT    rect;
  632.  
  633.     GetClientRect(hWndMain, &rect);
  634.     *width = (float) rect.right;
  635.     *height = (float) rect.bottom;
  636. }
  637.  
  638.  
  639. /* This dispatches any messages waiting and
  640.    waits in a loop if the application is not active. */
  641. void UpdateMessages (void)
  642. {
  643. MSG msg;
  644.  
  645.   PR_ReadMouse ();
  646.   PR_ReadKeyboard ();
  647.  
  648.   do {
  649.   while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
  650.   {
  651.    TranslateMessage(&msg);
  652.    DispatchMessage(&msg);      
  653.   }
  654.   } while (!PR_AppActive);
  655. }
  656.  
  657.  
  658.  
  659. char PR_getch (void)
  660. {
  661. MSG     msg;
  662. char    rv;
  663.  
  664.   if (keytail != keyhead)
  665.     {
  666.      rv = keyqueue[keytail++];
  667.      keytail &= 255;
  668.      return rv;
  669.     }
  670.  
  671.   while (GetMessage( &msg, NULL, 0, 0 ))
  672.     {
  673.      TranslateMessage (&msg);
  674.      DispatchMessage (&msg);
  675.  
  676.      if (keytail != keyhead)
  677.        {
  678.         rv = keyqueue[keytail++];
  679.         keytail &= 255;
  680.         return rv;
  681.        }
  682.     }
  683.    return rv;
  684. }
  685.  
  686.  
  687. int PR_kbhit (void)
  688. {
  689. MSG msg;
  690.  
  691.   if (keyhead != keytail)
  692.     return 1;
  693.  
  694.   while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
  695.     {
  696.      TranslateMessage (&msg);
  697.      DispatchMessage (&msg);      /* this might change keyhead */
  698.      if (keyhead != keytail)
  699.        return 1;
  700.     }
  701.   return 0;
  702. }
  703.  
  704.